﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Reflection;

using Microsoft.Xna.Framework.Graphics;
using TomShane.Neoforce.Controls;

namespace tactics.GUI
{
    public class GUIBuilder
    {
        // Launches the parsing of the xml file
        public static void BuildGUI(IGUIParsable caller, Manager guiManager, string xmlFile, string controlName)
        {
            XmlReader r = XmlReader.Create(xmlFile);

            r.Read(); // xml header
            r.Read(); // xml end entity
            r.Read(); // root level
            
            if (r.Name != controlName)
                return;

            while (r.Read())
            {
                ParseElement(caller, r, guiManager, null);
            }
            r.Close();
        }

        // parses an individual element (and its children, if any)
        private static void ParseElement(IGUIParsable caller, XmlReader r, Manager guiManager, Control parent)
        {
            if (r.Name == "")
                return;

            Control last = caller.Parse(r, r.Name);

            if (parent != null)
                parent.Add(last);
            else
                guiManager.Add(last);

            parent = last;

            if (r.NodeType == XmlNodeType.Element)
            {
                XmlReader sub = r.ReadSubtree();
                sub.Read(); sub.Read();
                while (sub.Read() && sub.NodeType != XmlNodeType.EndElement)
                {
                    if (sub.NodeType == XmlNodeType.Element)
                    {
                        ParseElement(caller, sub, guiManager, parent);
                    }
                }
            }
        }

        // converts strings from the xml into their datatypes based on the controls property types
        public static void ParseControl<ControlType>(XmlReader r, ControlType p)
        {
            PropertyInfo[] pi = typeof(ControlType).GetProperties();
            foreach (PropertyInfo prop in pi)
            {
                if (r.GetAttribute(prop.Name) != null)
                {
                    object value = null;
                    Type type = prop.PropertyType;

                    if (type == typeof(string))
                    {
                        value = r.GetAttribute(prop.Name);
                    }
                    else if (type == typeof(bool))
                    {
                        value = bool.Parse(r.GetAttribute(prop.Name));
                    }
                    else if (type == typeof(Color))
                    {
                        string[] colorInfo = r.GetAttribute(prop.Name).Split(',');
                        float red, green, blue, alpha;

                        red = float.Parse(colorInfo[0]);
                        green = float.Parse(colorInfo[1]);
                        blue = float.Parse(colorInfo[2]);
                        
                        if (colorInfo.Length > 3)
                            alpha = float.Parse(colorInfo[3]);
                        else
                            alpha = 1.0f;

                        Color c = new Color(red, green, blue, alpha);
                        value = c;
                    }
                    else if (type == typeof(Texture2D))
                    {
                        value = TacticsEngine.Instance.Content.Load<Texture2D>(r.GetAttribute("Image"));
                    }
                    else if (type == typeof(int))
                    {
                        value = int.Parse(r.GetAttribute(prop.Name));
                    }

                    prop.SetValue(p, value, null);
                }
            }
        }
    }
}
